From a2bc455f654e011c53968b0d3a14389d7259847e Mon Sep 17 00:00:00 2001 From: dujinkim Date: Wed, 3 Sep 2025 10:35:57 +0000 Subject: (최겸) 구매 입찰 개발(벤더 응찰 개발 및 기본계약 요청 개발 필) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/[lng]/evcp/(evcp)/bid/[id]/detail/page.tsx | 52 +++++++++++++ app/[lng]/evcp/(evcp)/bid/[id]/layout.tsx | 91 +++++++++++++++++++++++ app/[lng]/evcp/(evcp)/bid/[id]/page.tsx | 52 ++----------- app/[lng]/evcp/(evcp)/bid/[id]/pre-quote/page.tsx | 52 +++++++++++++ 4 files changed, 201 insertions(+), 46 deletions(-) create mode 100644 app/[lng]/evcp/(evcp)/bid/[id]/detail/page.tsx create mode 100644 app/[lng]/evcp/(evcp)/bid/[id]/layout.tsx create mode 100644 app/[lng]/evcp/(evcp)/bid/[id]/pre-quote/page.tsx (limited to 'app/[lng]') diff --git a/app/[lng]/evcp/(evcp)/bid/[id]/detail/page.tsx b/app/[lng]/evcp/(evcp)/bid/[id]/detail/page.tsx new file mode 100644 index 00000000..ac9b5df4 --- /dev/null +++ b/app/[lng]/evcp/(evcp)/bid/[id]/detail/page.tsx @@ -0,0 +1,52 @@ +import { Suspense } from 'react' +import { notFound } from 'next/navigation' +import { getBiddingDetailData } from '@/lib/bidding/detail/service' +import { BiddingDetailContent } from '@/lib/bidding/detail/table/bidding-detail-content' + +// 메타데이터 생성 +export async function generateMetadata({ params }: { params: Promise<{ id: string }> }) { + const { id } = await params + const parsedId = parseInt(id) + if (isNaN(parsedId)) return { title: '입찰 관리상세' } + + try { + const detailData = await getBiddingDetailData(parsedId) + return { + title: detailData.bidding ? `${detailData.bidding.title} - 입찰 관리상세` : '입찰 관리상세', + } + } catch { + return { title: '입찰 관리상세' } + } +} + +interface PageProps { + params: Promise<{ id: string }> +} + +export default async function Page({ params }: PageProps) { + const { id } = await params + const parsedId = parseInt(id) + + if (isNaN(parsedId)) { + notFound() + } + + // 통합 데이터 로딩 함수 사용 + const detailData = await getBiddingDetailData(parsedId) + + if (!detailData.bidding) { + notFound() + } + + return ( + 로딩 중...}> + + + ) +} diff --git a/app/[lng]/evcp/(evcp)/bid/[id]/layout.tsx b/app/[lng]/evcp/(evcp)/bid/[id]/layout.tsx new file mode 100644 index 00000000..b675aed1 --- /dev/null +++ b/app/[lng]/evcp/(evcp)/bid/[id]/layout.tsx @@ -0,0 +1,91 @@ +import { Metadata } from "next" + +import { Separator } from "@/components/ui/separator" +import { SidebarNav } from "@/components/layout/sidebar-nav" +import { getBiddingById, getBiddingConditions } from "@/lib/bidding/service" +import { Bidding } from "@/db/schema/bidding" +import { Button } from "@/components/ui/button" +import { ArrowLeft } from "lucide-react" +import Link from "next/link" +import { BiddingInfoHeader } from "@/components/bidding/bidding-info-header" +import { BiddingConditionsEdit } from "@/components/bidding/bidding-conditions-edit" +export const metadata: Metadata = { + title: "Bidding Detail", +} + +export default async function SettingsLayout({ + children, + params, +}: { + children: React.ReactNode + params: { lng: string , id: string} +}) { + + // 1) URL 파라미터에서 id 추출, Number로 변환 + const resolvedParams = await params + const lng = resolvedParams.lng + const id = resolvedParams.id + + const idAsNumber = Number(id) + // 2) DB에서 해당 입찰 정보 조회 + const bidding: Bidding | null = await getBiddingById(idAsNumber) + const biddingConditions = await getBiddingConditions(idAsNumber) + + // 3) 사이드바 메뉴 + const sidebarNavItems = [ + { + title: "입찰 사전견적", + href: `/${lng}/evcp/bid/${id}/pre-quote`, + }, + { + title: "입찰 관리상세", + href: `/${lng}/evcp/bid/${id}/detail`, + }, + ] + + return ( + <> +
+
+
+ {/* RFQ 목록으로 돌아가는 링크 추가 */} +
+ + + +
+
+ {/* 4) 입찰 정보가 있으면 번호 + 제목 + "상세 정보" 표기 */} +

+ {bidding + ? `${bidding.biddingNumber ?? ""} - ${bidding.title}` + : "Loading Bidding..."} +

+
+ {/* 입찰 정보 헤더 */} + + + {/* 입찰 조건 */} + {bidding && ( + + )} + + +
+ +
{children}
+
+
+
+
+ + ) +} \ No newline at end of file diff --git a/app/[lng]/evcp/(evcp)/bid/[id]/page.tsx b/app/[lng]/evcp/(evcp)/bid/[id]/page.tsx index e4051f9b..ca0788a5 100644 --- a/app/[lng]/evcp/(evcp)/bid/[id]/page.tsx +++ b/app/[lng]/evcp/(evcp)/bid/[id]/page.tsx @@ -1,52 +1,12 @@ -import { Suspense } from 'react' -import { notFound } from 'next/navigation' -import { getBiddingDetailData } from '@/lib/bidding/detail/service' -import { BiddingDetailContent } from '@/lib/bidding/detail/table/bidding-detail-content' - -// 메타데이터 생성 -export async function generateMetadata({ params }: { params: Promise<{ id: string }> }) { - const { id } = await params - const parsedId = parseInt(id) - if (isNaN(parsedId)) return { title: '입찰 상세' } - - try { - const detailData = await getBiddingDetailData(parsedId) - return { - title: detailData.bidding ? `${detailData.bidding.title} - 입찰 상세` : '입찰 상세', - } - } catch { - return { title: '입찰 상세' } - } -} +import { redirect } from 'next/navigation' interface PageProps { - params: Promise<{ id: string }> + params: Promise<{ lng: string; id: string }> } export default async function Page({ params }: PageProps) { - const { id } = await params - const parsedId = parseInt(id) - - if (isNaN(parsedId)) { - notFound() - } - - // 통합 데이터 로딩 함수 사용 - const detailData = await getBiddingDetailData(parsedId) - - if (!detailData.bidding) { - notFound() - } - - return ( - 로딩 중...}> - - - ) + const { lng, id } = await params + + // 기본적으로 입찰 사전견적 페이지로 리다이렉트 + redirect(`/${lng}/evcp/bid/${id}/pre-quote`) } diff --git a/app/[lng]/evcp/(evcp)/bid/[id]/pre-quote/page.tsx b/app/[lng]/evcp/(evcp)/bid/[id]/pre-quote/page.tsx new file mode 100644 index 00000000..e2c22b22 --- /dev/null +++ b/app/[lng]/evcp/(evcp)/bid/[id]/pre-quote/page.tsx @@ -0,0 +1,52 @@ +import { Suspense } from 'react' +import { notFound } from 'next/navigation' +import { getBiddingDetailData } from '@/lib/bidding/detail/service' +import { BiddingDetailContent } from '@/lib/bidding/detail/table/bidding-detail-content' + +// 메타데이터 생성 +export async function generateMetadata({ params }: { params: Promise<{ id: string }> }) { + const { id } = await params + const parsedId = parseInt(id) + if (isNaN(parsedId)) return { title: '입찰 사전견적' } + + try { + const detailData = await getBiddingDetailData(parsedId) + return { + title: detailData.bidding ? `${detailData.bidding.title} - 입찰 사전견적` : '입찰 사전견적', + } + } catch { + return { title: '입찰 사전견적' } + } +} + +interface PageProps { + params: Promise<{ id: string }> +} + +export default async function Page({ params }: PageProps) { + const { id } = await params + const parsedId = parseInt(id) + + if (isNaN(parsedId)) { + notFound() + } + + // 통합 데이터 로딩 함수 사용 + const detailData = await getBiddingDetailData(parsedId) + + if (!detailData.bidding) { + notFound() + } + + return ( + 로딩 중...}> + + + ) +} -- cgit v1.2.3